package com.zbkj.client.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.sun.net.httpserver.HttpsServer;
import com.zbkj.client.config.ClientTokenComponent;
import com.zbkj.client.service.ClientLoginService;
import com.zbkj.client.utils.ClientSecurityUtil;
import com.zbkj.common.model.admin.SystemAdmin;
import com.zbkj.common.model.client.agent.PackageConfig;
import com.zbkj.common.model.client.agent.PowerPointHistory;
import com.zbkj.common.model.client.agent.UserReadNotice;
import com.zbkj.common.model.client.agent.ClientSystemNotice;
import com.zbkj.common.model.client.workbench.VideoSplit;
import com.zbkj.common.vo.PowerPointHistoryVo;
import com.zbkj.common.vo.SystemNoticeVo;
import com.zbkj.common.request.ClientUpdatePasswordRequest;
import com.zbkj.common.response.ClientLoginResponse;
import com.zbkj.common.result.CommonResult;
import com.zbkj.common.utils.OssUtil;
import com.zbkj.common.vo.LoginUserVo;
import com.zbkj.service.service.PackageConfigService;
import com.zbkj.service.service.PowerPointHistoryService;
import com.zbkj.service.service.ClientSystemNoticeService;
import com.zbkj.service.service.UserReadNoticeService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import com.zbkj.service.service.SystemAdminService;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.LinkedHashMap;
import java.util.ArrayList;
import java.util.stream.Collectors;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.core.type.TypeReference;

@RestController
@RequestMapping("/api/client/user")
@Api(tags = "用户控制器")
public class UserController {

    @Autowired
    private SystemAdminService systemAdminService;

    @Autowired
    private ClientTokenComponent clientTokenComponent;

    @Autowired
    private ClientLoginService clientLoginService;

    @Autowired
    private PackageConfigService packageConfigService;

    @Autowired
    private PowerPointHistoryService powerPointHistoryService;

    @Autowired
    private ClientSystemNoticeService clientSystemNoticeService;

    @Autowired
    private UserReadNoticeService userReadNoticeService;

    /**
     * 获取当前登录用户信息
     */
    @ApiOperation(value = "获取当前登录用户信息")
    @GetMapping("/getUserInfo")
    public CommonResult<ClientLoginResponse> getUserInfo(HttpServletRequest request) {
        try {
            Integer userId = clientTokenComponent.getLoginUser(request);
            String token = request.getHeader("token");
            ClientLoginResponse userInfo = clientTokenComponent.getUserInfo(userId, token);

            ClientLoginResponse loginUser = (ClientLoginResponse) userInfo;
            if (loginUser == null) {
                return CommonResult.failed("用户不存在");
            }

            loginUser.setToken(token);
            return CommonResult.success(loginUser);
        } catch (Exception e) {
            return CommonResult.failed("获取用户信息失败：" + e.getMessage());
        }
    }

    @ApiOperation(value = "修改密码")
    @RequestMapping(value = "/resetPassword", method = RequestMethod.POST)
    public CommonResult<Map<String, Object>> updatePassword(@RequestBody @Validated ClientUpdatePasswordRequest request, HttpServletRequest httpRequest) {
        // 获取当前登录用户ID
        Integer userId = clientTokenComponent.getLoginUser(httpRequest);
        if (userId == null) {
            return CommonResult.failed("用户未登录");
        }

        Boolean result = clientLoginService.updatePassword(request, userId);
        if (result) {
            Map<String, Object> data = new HashMap<>();
            data.put("result", 1);
            return CommonResult.success(data);
        }
        return CommonResult.failed("密码修改失败");
    }

    /**
     * 获取当前登录用户信息
     */
    @ApiOperation(value = "获取当前登录用户使用的容量和剩余点数")
    @GetMapping("/getUse")
    public CommonResult<Map<String, Object>> getUse(HttpServletRequest request) {
        try {
            Integer userId = clientTokenComponent.getLoginUser(request);
            String token = request.getHeader("token");
            ClientLoginResponse userInfo = clientTokenComponent.getUserInfo(userId, token);

            Double powerPoint = clientTokenComponent.getMerchantPowerPoint(userInfo.getMerId());
            String storage = OssUtil.calculateFolderSizeFormatted("client/" + userInfo.getMerId());

            Map<String, Object> hashMap = new HashMap<>();
            hashMap.put("point", powerPoint);
            hashMap.put("storage", storage);

            return CommonResult.success(hashMap);
        } catch (Exception e) {
            return CommonResult.failed("获取用户信息失败：" + e.getMessage());
        }
    }

    /**
     * 获取当前租户下的扣点的历史记录（连表查询）
     */
    @ApiOperation(value = "获取当前租户下的扣点历史记录")
    @GetMapping("/getCostPointList")
    public CommonResult<IPage<PowerPointHistoryVo>> getCostPointList(@RequestParam(value = "page", defaultValue = "1") int page,
                                                              @RequestParam(value = "pageSize", defaultValue = "20") int pageSize,
                                                              HttpServletRequest request) {
        try {
            Integer userId = clientTokenComponent.getLoginUser(request);
            String token = request.getHeader("token");
            ClientLoginResponse userInfo = clientTokenComponent.getUserInfo(userId, token);
            Integer merId = userInfo.getMerId();

            Page<PowerPointHistoryVo> pageParam = new Page<>(page, pageSize);
            IPage<PowerPointHistoryVo> res = powerPointHistoryService.getPageWithUserInfo(pageParam, merId);

            return CommonResult.success(res);
        } catch (Exception e) {
            return CommonResult.failed("获取扣点历史记录失败：" + e.getMessage());
        }
    }

    /**
     * 获取通知列表
     */
    @ApiOperation(value = "获取通知列表")
    @GetMapping("/getNoticeList")
    public CommonResult<IPage<SystemNoticeVo>> getNoticeList(@RequestParam(value = "page", defaultValue = "1") int page,
                                                           @RequestParam(value = "pageSize", defaultValue = "20") int pageSize,
                                                           @RequestParam(value = "isRead", required = false) Integer isRead,
                                                           HttpServletRequest request) {
        try {
            Integer userId = clientTokenComponent.getLoginUser(request);
            if (userId == null) {
                return CommonResult.failed("用户未登录");
            }

            String token = request.getHeader("token");
            ClientLoginResponse userInfo = clientTokenComponent.getUserInfo(userId, token);
            Integer merId = userInfo.getMerId();

            Page<SystemNoticeVo> pageParam = new Page<>(page, pageSize);
            IPage<SystemNoticeVo> res = clientSystemNoticeService.getNoticeListWithReadStatus(pageParam, userId, merId, isRead);

            return CommonResult.success(res);
        } catch (Exception e) {
            return CommonResult.failed("获取通知列表失败：" + e.getMessage());
        }
    }

    /**
     * 用户读取消息
     */
    @ApiOperation(value = "用户读取消息")
    @PostMapping("/readNotice")
    public CommonResult<String> readNotice(@RequestBody Map<String, Object> requestBody,
                                                      HttpServletRequest httpRequest) {
        try {
            // 从请求体中获取noticeId
            Integer noticeId = (Integer)requestBody.get("noticeId");
            
            // 获取当前登录用户ID
            Integer userId = clientTokenComponent.getLoginUser(httpRequest);
            if (userId == null) {
                return CommonResult.failed("用户未登录");
            }

            // 获取用户信息和租户ID
            String token = httpRequest.getHeader("token");
            ClientLoginResponse userInfo = clientTokenComponent.getUserInfo(userId, token);
            Integer merId = userInfo.getMerId();

            // 检查是否已经标记为已读
            long count = userReadNoticeService.lambdaQuery()
                    .eq(UserReadNotice::getUserId, userId)
                    .eq(UserReadNotice::getMerId, merId)
                    .eq(UserReadNotice::getNoticeId, noticeId)
                    .count();

            if (count > 0) {
                return CommonResult.success("该通知已标记为已读", "该通知已标记为已读");
            }

            // 创建已读记录
            UserReadNotice userReadNotice = new UserReadNotice();
            userReadNotice.setUserId(userId);
            userReadNotice.setMerId(merId);
            userReadNotice.setNoticeId(noticeId);
            userReadNotice.setCreateTime(new Date());
            userReadNotice.setUpdateTime(new Date());

            boolean result = userReadNoticeService.save(userReadNotice);
            if (result) {
                return CommonResult.success("标记已读成功", "标记已读成功");
            } else {
                return CommonResult.failed("标记已读失败");
            }
        } catch (Exception e) {
            return CommonResult.failed("标记已读失败：" + e.getMessage());
        }
    }

    /**
     * 用户一键已读所有未读消息
     */
    @ApiOperation(value = "用户一键已读所有未读消息")
    @PostMapping("/oneClickReadNotice")
    public CommonResult<String> oneClickReadNotice(HttpServletRequest httpRequest) {
        try {
            // 1. 获取当前登录用户ID
            Integer userId = clientTokenComponent.getLoginUser(httpRequest);
            if (userId == null) {
                return CommonResult.failed("用户未登录");
            }

            // 2. 获取用户信息和租户ID
            String token = httpRequest.getHeader("token");
            ClientLoginResponse userInfo = clientTokenComponent.getUserInfo(userId, token);
            Integer merId = userInfo.getMerId();

            // 3. 查询该用户下所有未读消息
            // 先获取所有系统通知
            List<ClientSystemNotice> allNotices = clientSystemNoticeService.list();
            
            // 查询用户已读的消息ID列表
            List<Integer> readNoticeIds = userReadNoticeService.lambdaQuery()
                    .eq(UserReadNotice::getUserId, userId)
                    .eq(UserReadNotice::getMerId, merId)
                    .list()
                    .stream()
                    .map(UserReadNotice::getNoticeId)
                    .collect(Collectors.toList());

            // 过滤出未读消息
            List<ClientSystemNotice> unreadNotices = allNotices.stream()
                    .filter(notice -> !readNoticeIds.contains(notice.getId()))
                    .collect(Collectors.toList());

            if (unreadNotices.isEmpty()) {
                return CommonResult.success("没有未读消息", "没有未读消息");
            }

            // 4. 批量创建已读记录
            List<UserReadNotice> readNoticeList = new ArrayList<>();
            Date now = new Date();
            
            for (ClientSystemNotice notice : unreadNotices) {
                UserReadNotice userReadNotice = new UserReadNotice();
                userReadNotice.setUserId(userId);
                userReadNotice.setMerId(merId);
                userReadNotice.setNoticeId(notice.getId());
                userReadNotice.setCreateTime(now);
                userReadNotice.setUpdateTime(now);
                readNoticeList.add(userReadNotice);
            }

            // 批量保存
            boolean result = userReadNoticeService.saveBatch(readNoticeList);
            if (result) {
                return CommonResult.success("一键已读成功，共标记 " + unreadNotices.size() + " 条消息为已读", 
                                         "一键已读成功，共标记 " + unreadNotices.size() + " 条消息为已读");
            } else {
                return CommonResult.failed("一键已读失败");
            }
        } catch (Exception e) {
            return CommonResult.failed("一键已读失败：" + e.getMessage());
        }
    }

    @ApiOperation(value = "更新用户头像")
    @RequestMapping(value = "/updateHeadImg", method = RequestMethod.POST)
    public CommonResult<String> updateHeadImg(@RequestBody Map<String, Object> params, HttpServletRequest httpRequest) {
        // 获取当前登录用户ID
        Integer userId = clientTokenComponent.getLoginUser(httpRequest);
        Integer materialId = (Integer)params.get("materialId");
        if (materialId == null) {
            return CommonResult.failed("请选择素材");
        }

        String token = httpRequest.getHeader("token");
        ClientLoginResponse userInfo = clientTokenComponent.getUserInfo(userId, token);
        Integer merId = userInfo.getMerId();

        Boolean result = clientLoginService.updateHeadImg(materialId, userId, merId);
        if (result) {
            return CommonResult.success("头像修改成功");
        }

        return CommonResult.failed("密码修改失败");
    }
} 